package edu.thu.studio.ormdesigner.editor.editpart;

import java.beans.PropertyChangeEvent;
import java.util.ArrayList;
import java.util.List;

import org.eclipse.draw2d.FreeformLayer;
import org.eclipse.draw2d.FreeformLayout;
import org.eclipse.draw2d.IFigure;
import org.eclipse.gef.CompoundSnapToHelper;
import org.eclipse.gef.EditPolicy;
import org.eclipse.gef.SnapToGeometry;
import org.eclipse.gef.SnapToGrid;
import org.eclipse.gef.SnapToHelper;
import org.eclipse.gef.editpolicies.SnapFeedbackPolicy;

import edu.thu.studio.ormdesigner.editor.policy.DiagramLayoutEditPolicy;
import edu.thu.studio.ormdesigner.model.diagram.Diagram;

public class DiagramEditPart extends AbstractModelEditPart {
    
    /**
     * {@inheritDoc}
     */
    @Override
    protected IFigure createFigure() {
        FreeformLayer layer = new FreeformLayer();
        layer.setLayoutManager(new FreeformLayout());
        return layer;
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    protected void createEditPolicies() {
        this.installEditPolicy(EditPolicy.LAYOUT_ROLE, new DiagramLayoutEditPolicy());
        this.installEditPolicy("Snap Feedback", new SnapFeedbackPolicy());
    }
    
    @Override
    @SuppressWarnings("rawtypes")
    protected List getModelChildren() {
        List<Object> modelChildren = new ArrayList<Object>();
        
        Diagram diagram = (Diagram) this.getModel();
        
        modelChildren.addAll(diagram.getNodes().getObjectList());
        
        return modelChildren;
    }
    
    @Override
    public void doPropertyChange(PropertyChangeEvent event) {
        if (event.getPropertyName().equals("refreshChildren")) {
            this.refreshChildren();
        } else if (event.getPropertyName().equals("refreshConnection")) {
            this.refreshConnectionVisuals();
        } else if (event.getPropertyName().equals("refreshWithConnection")) {
            this.refresh();
            this.refreshConnectionVisuals();
            this.getViewer().deselectAll();
        }
        super.doPropertyChange(event);
    }
    
    private void refreshConnectionVisuals() {
        
    }
    
    /**
     * {@inheritDoc}
     */
    @Override
    public void refreshVisuals() {
        for (Object child : this.getChildren()) {
            if (child instanceof NodeEditPart) {
                NodeEditPart part = (NodeEditPart) child;
                part.refreshVisuals();
            }
        }
    }
    
    @Override
    @SuppressWarnings("rawtypes")
    public Object getAdapter(Class key) {
        
        if (key == SnapToHelper.class) {
            List<SnapToHelper> helpers = new ArrayList<SnapToHelper>();
            
            helpers.add(new SnapToGeometry(this));
            
            if (Boolean.TRUE.equals(getViewer().getProperty(SnapToGeometry.PROPERTY_SNAP_ENABLED))) {
                helpers.add(new SnapToGrid(this));
            }
            
            if (helpers.size() == 0) {
                return null;
                
            } else {
                return new CompoundSnapToHelper(helpers.toArray(new SnapToHelper[0]));
            }
        }
        
        return super.getAdapter(key);
    }
    
}
